package com.terrace.controller.system;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.terrace.core.common.model.ResultData;
import com.terrace.db.system.mapper.entity.Permission;
import com.terrace.db.system.service.PermissionService;
import com.terrace.core.mybatis.entity.Pagination;
import com.terrace.core.utils.CustomArrayUtils;
import com.terrace.core.utils.UUIDGenerator;
import com.terrace.core.utils.validation.ValidationHelper;
import com.terrace.web.annotation.Logs;
import com.terrace.web.constant.GlobalsConstant;
import com.terrace.web.model.DataGrid;
import com.terrace.web.tagext.easyui.model.ComboTreeModel;
import com.terrace.web.tagext.easyui.model.TreeGridModel;
import com.terrace.web.tagext.easyui.utils.TreeUIUtils;

/**
 * 权限管理
 * @author jiangyg
 *
 */
@Controller
@Scope("prototype")
@RequestMapping("/permission")
public class PermissionController {
	
	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(PermissionController.class);
	
	private static final String MESSAGE_TYPE = "权限信息";
	
	@Autowired
	private PermissionService permissionService;
	
	/**
	 * 默认管理页面
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "menuList")
	public ModelAndView menuList(HttpServletRequest request){
		return new ModelAndView("system/permission/menuList");
	}
	
	/**
	 * 菜单页面
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "menu")
	public ModelAndView menu(String id, String parentPermiId, HttpServletRequest request){
		if (StringUtils.isNotBlank(id)) {
			request.setAttribute("menu", permissionService.selectByPermissionId(id));
		}
		if (StringUtils.isNotBlank(parentPermiId)) {
			request.setAttribute("parentMenu", permissionService.selectByPermissionId(parentPermiId));
		}
		return new ModelAndView("system/permission/menu");
	}
	
	/**
	 * 权限管理
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "permissionList")
	public ModelAndView permissionList(@RequestParam(value = "permissionId") String permissionId, HttpServletRequest request){
		request.setAttribute("permissionId", permissionId);
		return new ModelAndView("system/permission/permissionList");
	}
	
	/**
	 * 权限页面
	 * @param permissionId
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "permission")
	public ModelAndView permission(String id, String parentPermiId, HttpServletRequest request){
		if (StringUtils.isNotBlank(id)) {
			request.setAttribute("permission", permissionService.selectByPermissionId(id));
		}
		if (StringUtils.isNotBlank(parentPermiId)) {
			request.setAttribute("parentMenu", permissionService.selectByPermissionId(parentPermiId));
		}
		return new ModelAndView("system/permission/permission");
	}
	
	/**
	 * 保存菜单或者权限
	 * @param permission
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequiresRoles(GlobalsConstant.Roles.ADMIN)
	@RequestMapping(params = "saveOrUpdate")
	@Logs(depict = "保存权限", type = GlobalsConstant.LogTypes.SYS_PERMISSION)
	@RequiresPermissions(value = { "system:menu:save", "system:permission:save" })
	public ResultData saveOrUpdate(Permission permission, HttpServletRequest request) {
		ResultData rd = new ResultData();
		ValidationHelper helper = ValidationHelper.valid(permission);
		if (helper.hasError()) {
			rd.setResult(helper.getErrors());
			return rd.failObjs("13105");
		}
		if (StringUtils.isBlank(permission.getId())) {
			permission.setId(UUIDGenerator.generate());
			permissionService.savePermissionSelective(permission);
			rd.successObjs("10001", MESSAGE_TYPE);
		} else {
			Permission temp = permissionService.selectByPermissionId(permission.getId());
			if (temp == null) {
				return rd.failObjs("13103", MESSAGE_TYPE);
			}
			permissionService.updateByPermissionIdSelective(permission);
			rd.successObjs("10002", MESSAGE_TYPE);
		}
		return rd;
	}
	
	/**
	 * 批量保存角色权限
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequiresRoles(GlobalsConstant.Roles.ADMIN)
	@RequiresPermissions("system:permission:empower")
	@RequestMapping(params = "batchSaveRolePermission")
	@Logs(depict = "角色赋权", type = GlobalsConstant.LogTypes.SYS_PERMISSION)
	public ResultData batchSaveRolePermission(HttpServletRequest request) {
		ResultData rd = new ResultData();
		// 参数
		String roleId = request.getParameter("roleId");
		String permissionIdStrs = request.getParameter("permissionIdStrs");
		String permiType = request.getParameter("permiType");
		String parentPermiId = request.getParameter("parentPermiId");
		if (StringUtils.isBlank(roleId) || StringUtils.isBlank(permiType)
				|| (StringUtils.equals(permiType, "2") && StringUtils.isBlank(parentPermiId))) {
			return rd.failObjs("13105");
		}
		
		// 原有的权限ID
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("roleId", roleId);
		condition.put("permiType", permiType);
		condition.put("parentPermiId", parentPermiId);
		List<String> originalPermissionIds = permissionService.selectPermiIdsByCondition(condition);
		
		// 新的要授权的权限ID
		List<String> newPermissionIds = Arrays.asList(permissionIdStrs.split(","));
		
		// 抽取要删除的权限ID
		List<String> deletePermissionIds = CustomArrayUtils.extractOriginalExcludeNewForArray(originalPermissionIds, newPermissionIds);
		
		if (deletePermissionIds.size() > 0) {
			int delResult = permissionService.batchDeleteRolePermissionByRoleId(roleId, deletePermissionIds);
			
			if (delResult != deletePermissionIds.size()) {
				rd.setStatus("13101");
				rd.setMessage("批量删除权限失败");
				return rd;
			}
		}
		
		// 抽取要保存的权限ID
		List<String> savePermissionIds = CustomArrayUtils.extractNewExcludeOriginalForArray(originalPermissionIds, newPermissionIds);
		if (savePermissionIds.size() > 0) {
			int saveResult = permissionService.batchSaveRolePermission(roleId, savePermissionIds);
			if (saveResult != savePermissionIds.size()) {
				rd.setStatus("13101");
				rd.setMessage("批量保存权限失败");
				return rd;
			}
		}
		return rd.success("保存角色权限成功！");
	}
	
	/**
	 * 删除权限或者菜单
	 * @param permissionId
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping(params = "delete")
	@RequiresRoles(GlobalsConstant.Roles.ADMIN)
	@Logs(depict = "删除权限", type = GlobalsConstant.LogTypes.SYS_PERMISSION)
	@RequiresPermissions(value = { "system:menu:delete", "system:permission:delete" })
	public ResultData delete(@RequestParam(value = "id") String permissionId, HttpServletRequest request) {
		ResultData rd = new ResultData();
		Permission permission = permissionService.selectByPermissionId(permissionId);
		if (permission == null) {
			return rd.failObjs("13103", MESSAGE_TYPE);
		} else {
			if (permission.getChildrenPermis().size() > 0) {
				return rd.fail("请先删除[" + permission.getPermiName() + "]下的权限或者菜单");
			}
			int result = permissionService.deleteByPermissionId(permissionId);
			if (result != 1) {
				rd.failObjs("13102", MESSAGE_TYPE);
			} else {
				rd.successObjs("10003", MESSAGE_TYPE);
			}
		}
		return rd;
	}
	
	/**
	 * 数据表格
	 * @param request
	 * @param pagination
	 * @return
	 */
	@RequestMapping(params = "treegrid")
	@RequiresPermissions("system:permission:treegrid:view")
	public void treegrid(Permission permission, Pagination<Permission> pagination, HttpServletResponse response) {
		try {
			// 查询子节点
			if (StringUtils.isNotBlank(permission.getId())) {
				permission.setParentPermiId(permission.getId());
				permission.setId(null);
				pagination.setPagination(false);
			}
			pagination = permissionService.selectPermissionsForPagination(permission, pagination);
			TreeGridModel model = new TreeGridModel(Permission.class, "childrenPermis");
			TreeUIUtils.createTreeGridJson(model, pagination, response);
		} catch (Exception e) {
			logger.error("生成TreeGrid失败：", e);
		}
	}
	
	/**
	 * 数据表格
	 * @param request
	 * @param pagination
	 * @return
	 */
	@ResponseBody
	@RequestMapping(params = "datagrid")
	@RequiresPermissions("system:permission:datagrid:view")
	public DataGrid<Permission> datagrid(Permission permission, Pagination<Permission> pagination, HttpServletRequest request) {
		DataGrid<Permission> dataGrid = new DataGrid<Permission>();
		dataGrid.setPagination(permissionService.selectPermissionsForPagination(permission, pagination));
		return dataGrid;
	}
	
	/**
	 * 生成权限树
	 * @param permission
	 * @param response
	 */
	@RequestMapping(params = "comboTree")
	@RequiresPermissions("system:permission:combotree:view")
	public void comboTree(String roleId, Permission permission, HttpServletResponse response) {
		try {
			
			// 查询树列表
			Pagination<Permission> pagination = new Pagination<Permission>(false);
			pagination = permissionService.selectPermissionsForPagination(permission, pagination);
			
			// 查询选中权限
			List<String> selectList = null;
			if (StringUtils.isNotBlank(roleId)) {
				Map<String, Object> condition = new HashMap<String, Object>();
				condition.put("roleId", roleId);
				condition.put("permiType", permission.getPermiType());
				condition.put("parentPermiId", permission.getParentPermiId());
				selectList = permissionService.selectPermiIdsByCondition(condition);
			}
			
			ComboTreeModel model = new ComboTreeModel(Permission.class, "id", "permiName", "childrenPermis");
			TreeUIUtils.createComboTreeJson(model, pagination.getResult(), selectList, response);
		} catch (Exception e) {
			logger.error("生成Tree失败：", e);
		}
	}
	
}
